;================================================================
;  end.s
;               The effect for the end part
;
;================================================================
;
; 25thanni, a demo dedicated to the 25th anniversary of the ZX81.
;
; (c)2006 Bodo Wenzel
;
; This program is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License as
; published by the Free Software Foundation; either version 2 of
; the License, or (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public
; License along with this program; if not, write to the Free
; Software Foundation Inc., 59 Temple Place, Suite 330, Boston,
; MA 02111-1307 USA
;================================================================

	.module	end

;= Externals ====================================================

	.globl	heap_ptr
	.globl	hrg_file

	.globl	set_show
	.globl	show_dummy
	.globl	vsync
	.globl	b_check

	.globl	G0,G1,G2,G3,G4,G5,G6,G7,G8,G9,GA,GB,GC,GD,GE,GF
	.globl	__,X8,X9,XA,QU,PD,DL,CL,QM,LP,RP,GT,LT,EQ,PL,MI
	.globl	TI,SL,SC,CM,PE,_0,_1,_2,_3,_4,_5,_6,_7,_8,_9
	.globl	_A,_B,_C,_D,_E,_F,_G,_H,_I,_J,_K,_L,_M,_N,_O,_P
	.globl	_Q,_R,_S,_T,_U,_V,_W,_X,_Y,_Z,NL,INV

	.globl	HRG_WIDTH,HRG_HEIGHT
	.globl	show_hrg
	.globl	h_in_fall
	.globl	h_out_center
	.globl	h_check

	.globl	unpack

;= Constants ====================================================

; double global definition checked by linker
INV		==	0x80
HRG_WIDTH	==	256
HRG_HEIGHT	==	192

BITS_PER_BYTE	=	8
BYTES_PER_WORD	=	2

HRG_BYTE_WIDTH	=	HRG_WIDTH/BITS_PER_BYTE

BITS_PER_PIXEL	=	3
PIC_WIDTH	=	64
PIC_HEIGHT	=	64
PIC_BYTE_WIDTH	=	PIC_WIDTH/BITS_PER_BYTE
PIC_SIZE	=	PIC_HEIGHT*PIC_BYTE_WIDTH

GFX_BLANK	=	(HRG_BYTE_WIDTH-PIC_BYTE_WIDTH)/2
GFX_SIZE	=	PIC_HEIGHT*HRG_BYTE_WIDTH

;= Program code =================================================

	.area	CODE

;- Show the effect ----------------------------------------------

end::
	ld	hl,#show_dummy
	call	set_show

	ld	hl,(heap_ptr)
	ld	de,#logo
	ld	bc,#PAC_LG_SIZE
	call	unpack

	dec	de
	ld	hl,#BITS_PER_PIXEL*PIC_HEIGHT*2*GFX_BLANK
	add	hl,de
	call	copy_pic
	call	copy_pic
	call	copy_pic

	ld	hl,#black_line
	ld	b,#HRG_BYTE_WIDTH
e_bl_loop:
	ld	(hl),#~0
	inc	hl
	djnz	e_bl_loop

	ld	hl,(heap_ptr)
	ld	bc,#BITS_PER_PIXEL*GFX_SIZE
	add	hl,bc

	ld	(hrg_file_1),hl
	call	prep_black
	ld	de,(heap_ptr)
	call	prep_pic
	ld	(hrg_file_2),hl
	push	de
	call	prep_black
	pop	de
	call	prep_pic
	ld	(hrg_file_3),hl
	ld	(hrg_file),hl
	push	de
	call	prep_black
	pop	de
	call	prep_pic
	call	prep_black

	call	h_in_fall

	ld	hl,#scroll_line
	ld	(show_hrg),hl
	ld	hl,#show_hrg
	call	set_show

	scf
	push	af
e_loop:
	call	vsync
	ld	hl,(hrg_file_1)
	ld	(hrg_file),hl
	call	vsync
	ld	hl,(hrg_file_2)
	ld	(hrg_file),hl
	call	vsync
	ld	hl,(hrg_file_3)
	ld	(hrg_file),hl

	pop	af
	push	af
	call	c,b_check
	jr	nz,e_loop	; bottom scroller not finished?

	pop	af
	call	c,h_out_center
	xor	a
	push	af

	call	h_check
	jr	nz,e_loop	; roll out not finished?

	pop	af

	ld	hl,(hrg_file)
	ld	de,#(HRG_HEIGHT/2-1)*BYTES_PER_WORD
	add	hl,de
	ld	e,(hl)
	inc	hl
	ld	d,(hl)
	ld	l,e
	ld	h,d
	ld	bc,#HRG_BYTE_WIDTH
	add	hl,bc
	push	hl
	push	de
	exx
	pop	de
	pop	hl
	dec	hl
	exx
	ld	e,l
	ld	d,h
	add	hl,bc
	dec	hl
	rr	c
e_q_lp1:
	ld	a,#2*BITS_PER_BYTE
e_q_lp2:
	push	af
	push	hl
	rra
	call	nc,vsync
	pop	hl
	ld	a,(hl)
	add	a,a
	ld	(hl),a
	ld	a,(de)
	and	a
	rra
	ld	(de),a
	exx
	pop	af
	dec	a
	jr	nz,e_q_lp2
	dec	hl
	inc	de
	exx
	dec	hl
	inc	de
	exx
	dec	c
	jr	nz,e_q_lp1	; the electron ray ceases...

	ret

;- Copy the logo picture into the bitmap ------------------------
; This routine must be called in sequence for all BITS_PER_PIXEL.
; DE	pointer to end of bitmap
; HL	pointer to end of picture

copy_pic:
	ld	c,#PIC_HEIGHT
cp_olp:
	ld	b,#GFX_BLANK
cp_rlp:
	ld	(hl),#~0
	dec	hl
	djnz	cp_rlp		; blacken right side

	ld	b,#PIC_BYTE_WIDTH
cp_clp:
	ld	a,(de)
	ld	(hl),a
	dec	de
	dec	hl
	djnz	cp_clp		; copy picture line

	ld	b,#GFX_BLANK
cp_llp:
	ld	(hl),#~0
	dec	hl
	djnz	cp_llp		; blacken left side

	dec	c
	jr	nz,cp_olp

	ret

;- Prepare table of pointers to black parts ---------------------
; HL	pointer to table to prepare

prep_black:
	ld	de,#black_line
	ld	bc,#((HRG_HEIGHT-PIC_HEIGHT)/2)<<BITS_PER_BYTE
	jr	pp_loop

;- Prepare table of pointers to a picture -----------------------
; DE	pointer to bitmap
; HL	pointer to table to prepare

prep_pic:
	ld	bc,#(PIC_HEIGHT<<BITS_PER_BYTE)+HRG_BYTE_WIDTH
pp_loop:
	ld	(hl),e
	inc	hl
	ld	(hl),d
	inc	hl

	ld	a,e
	add	a,c
	ld	e,a
	jr	nc,pp_next
	inc	d
pp_next:
	djnz	pp_loop

	ret

;= Data =========================================================

; Three pictures because of the grey pixels:
logo:
	.include	"hidd_lg.inc"
PAC_LG_SIZE	=	.-logo
UNP_LG_SIZE	=	UNPACKED
	.if	UNP_LG_SIZE-BITS_PER_PIXEL*PIC_SIZE
	.error	"Wrong size of logo"
	.endif

scroll_line:
	.db	__,INV+_S,INV+_O,__,_Y,_O,_U,__,_F,_O,_U,_N,_D,__
	.db	_T,_H,_E,__,_H,_I,_D,_D,_E,_N,__,_P,_A,_R,_T,PE
	.db	NL

;= Variables ====================================================

	.area	SCRATCH	(ovr)

hrg_file_1:
	.dw	0
hrg_file_2:
	.dw	0
hrg_file_3:
	.dw	0
black_line:
	.ds	HRG_BYTE_WIDTH

;= Heap usage ===================================================

;		unpacked logo data
HEAP1 =		BITS_PER_PIXEL*PIC_SIZE

;		bitmaps of all picture parts
HEAP2 =		BITS_PER_PIXEL*GFX_SIZE
;		pointer table for black part
HEAP2 =	HEAP2 +	(HRG_HEIGHT-PIC_HEIGHT)/2*BYTES_PER_WORD
;		pointer table for picture 1 part
HEAP2 =	HEAP2 +	PIC_HEIGHT*BYTES_PER_WORD
;		pointer table for black part
HEAP2 =	HEAP2 +	(HRG_HEIGHT-PIC_HEIGHT)/2*BYTES_PER_WORD
;		pointer table for picture 2 part
HEAP2 =	HEAP2 +	PIC_HEIGHT*BYTES_PER_WORD
;		pointer table for black part
HEAP2 =	HEAP2 +	(HRG_HEIGHT-PIC_HEIGHT)/2*BYTES_PER_WORD
;		pointer table for picture 3 part
HEAP2 =	HEAP2 +	PIC_HEIGHT*BYTES_PER_WORD
;		pointer table for black part
HEAP2 =	HEAP2 +	(HRG_HEIGHT-PIC_HEIGHT)/2*BYTES_PER_WORD

	.area	HEAP	(abs,ovr)
	.if	HEAP1/HEAP2
	.ds	HEAP1
	.else
	.ds	HEAP2
	.endif

;= The end ======================================================
